#include "../utils/pch.h"
#include "../utils/IniReader.h"
#include "../utils/PcapUtils.h"
#include "../utils/PduUtils.h"
#include "main.h"

#define HOME_DIR "/tmp/tmp.FdUHWCPhyb/"

namespace ntp{
    // 定义全局变量
    std::string global_message = "Hello, World!";
    std::mutex global_mutex;


    // 共享的数据结构
    struct shareData{
        std::string tf_info; // 流量信息
    } sd;

    // 共享的日志对象
    std::shared_ptr<spdlog::logger> my_nm_logger;

}

// 项目环境测试
/*int main2() {
    std::shared_ptr<spdlog::logger> my_logger = spdlog::basic_logger_mt("basic_logger", "basic_logger.txt");
    my_logger->info("工作函数{},{},{}",1,2,3);
    spdlog::info("控制台日志");
    std::cout << "Hello, World!" << std::endl;


    IniReader* iniCfg = new IniReader();
    std::string cfgPathName = HOME_DIR"/my_config.ini";
    if (!iniCfg->ReadConfig(cfgPathName)) {
        std::cout << "读取 ini 配置文件失败" << std::endl;
    }
    else {
        std::cout << "读取 my_config.ini 配置文件成功" << std::endl;
    }

    std::string g_chFrontaddr = iniCfg->ReadString("config", "FrontAddr","");

    std::string f1 = iniCfg->ReadString("FILE", "file_path_1","");
    std::string f2 = iniCfg->ReadString("FILE", "file_path_2","");

    std::cout << "f1=" << f1 << " f2=" << f2 << std::endl;

    // pcap库测试
    PcapUtils pcapUtils;
    //pcapUtils.readPcapFile();
    //pcapUtils.readNetworkInterface();
    //pcapUtils.readNetworkIface();
    //pcapUtils.readNetworkIface4();

    // Tins 库测试
    PduUtils pduUtils;
    //pduUtils.utilMain();

    // =============================================================
    // 使用std::async启动一个异步任务
    //std::future<void> result = std::async(std::launch::async, pcapUtils.readPcapFile());

    // =============================================================


    // 创建一个异步的读取线程
    pthread_t thread2;
*//*    if (pthread_create(&thread2, nullptr,reinterpret_cast<void *(*)(void *)>(pcapUtils.readMsg()), nullptr ) != 0) {
        std::cerr << "create thread err!" << std::endl;
        return -1;
    }*//*


    std::cout<< "休眠 5s" << std::endl;
    //sleep(5);


    // 创建一个异步的写入线程
    pthread_t thread;
    void *ret_val = nullptr;
*//*    if (pthread_create(&thread, nullptr, reinterpret_cast<void *(*)(void *)>(pcapUtils.readPcapFile()), nullptr ) != 0) {
        std::cerr << "create thread err!" << std::endl;
        return -1;
    }*//*


    // 异步
    //std::future<std::string> fut = std::async(std::launch::async, &PcapUtils::readPcapFile, &pcapUtils);
    //std::future<std::vector<char>> future = std::async(std::launch::async, &PcapUtils::readPcapFile );
    //std::thread requestThread(pcapUtils.readPcapFile());


    // 等待线程结束

*//*    if (pthread_join(thread, &ret_val) != 0 && pthread_join(thread2, &ret_val) != 0) {
        std::cerr << "get compute result err!" << std::endl;
        return -2;
    } else {
        if (nullptr == ret_val) {
            std::cerr << "get compute result fail!"
                      << std::endl;
            return -3;
        } else {
            std::cout << "get compute result:"
                      << *static_cast<int*>(ret_val)
                      << std::endl;
        }
    }*//*



    return 0;
}*/


int main() {
    // 初始化运行时日志
    std::shared_ptr<spdlog::logger> my_logger = spdlog::basic_logger_mt("test_logger", "runingTimeLogger.txt"); // basic_logger 固定写法
    spdlog::set_default_logger(my_logger);
    spdlog::flush_on(spdlog::level::info);
    spdlog::get("test_logger")->info("LoggingTest::ctor");

    my_logger->info("============================ 程序开始执行 ============================");
    std::cout << "启动程序 " << my_logger->name() << std::endl;

    // 获取启动时间
    auto aa = currTime();
    // 获取当前时间作为启动时间
    std::chrono::system_clock::time_point startTime = std::chrono::system_clock::now();
    // 获取当前工作路径
    char cwd[1024];
    if (getcwd(cwd, sizeof(cwd)) == NULL) {
        perror("getcwd");
        return 1;
    }

    // 初始化配置文件对象
    IniReader* iniCfg = new IniReader();
    std::string cwdStr(cwd);
    std::string cfgPathName = cwdStr + "/my_config.ini";
    //std::string cfgPathName = HOME_DIR"/my_config.ini";

    my_logger->info("程序启动路径为：{} ,启动时间：{}", cwd, aa);
    my_logger->info("读取的配置文件：{}", cfgPathName);

    if (!iniCfg->ReadConfig(cfgPathName)) {
        my_logger->info("读取 ini 配置文件失败");
        //std::cout << "读取 ini 配置文件失败" << std::endl;
    }
    else {
        my_logger->info("读取 my_config.ini 配置文件成功");
        //std::cout << "读取 my_config.ini 配置文件成功" << std::endl;
    }

    // iniCfg


    // pcap库测试
    PcapUtils pcapUtils(my_logger);
    //PcapUtils pcapUtils;
    //pcapUtils.readPcapFile();
    //pcapUtils.readNetworkInterface();
    //pcapUtils.readNetworkIface();
    //pcapUtils.readNetworkIface4();


    // 读取两路行情，用同一个起点做对比
    auto readLambda = [](PcapUtils pcapUtils, std::shared_ptr<spdlog::logger> my_logger, IniReader* iniCfg, std::chrono::system_clock::time_point startTime) {
        my_logger->info("消费者线程 - 启动读行情线程");
        pcapUtils.readMsg(my_logger, iniCfg);
    };
    std::thread task2(readLambda, pcapUtils, my_logger, iniCfg, startTime);

    // 写行情1
    auto writeLambda = [](PcapUtils pcapUtils, std::shared_ptr<spdlog::logger> my_logger, IniReader* iniCfg, std::chrono::system_clock::time_point startTime) {
        my_logger->info("生产者线程1 - 启动读行情线程1");
        pcapUtils.readNetworkIfaceLine1(startTime, iniCfg);
    };
    std::thread task(writeLambda, pcapUtils, my_logger, iniCfg, startTime);

    // 写行情2
    auto writeLambda2 = [](PcapUtils pcapUtils, std::shared_ptr<spdlog::logger> my_logger, IniReader* iniCfg, std::chrono::system_clock::time_point startTime) {
        my_logger->info("生产者线程2 - 启动读行情线程2");
        pcapUtils.readNetworkIfaceLine2(startTime, iniCfg);
    };
    std::thread task3(writeLambda2, pcapUtils, my_logger, iniCfg, startTime);

    // 采样统计
    auto sampledLambda = [](PcapUtils pcapUtils, std::shared_ptr<spdlog::logger> my_logger, IniReader* iniCfg, std::chrono::system_clock::time_point startTime) {
        my_logger->info("采样统计线程 - 启动读行情线程");
        pcapUtils.sampled(my_logger, iniCfg);
    };
    std::thread task4(sampledLambda, pcapUtils, my_logger, iniCfg, startTime);

    // 等待线程结束
    task2.join();
    task.join();
    task3.join();
    task4.join();

}





